package com.wushijia.highconcurrency.condition;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 顺序打印sub1,sub2,sub3
 */
public class ThreeConditionCommunication {

  public static void main(String[] args) {
    final Business business = new Business();
    new Thread(()->{
      for (int i = 0; i < 10; i++) {
       business.sub1();
      }
    }).start();
    new Thread(()->{
      for (int i = 0; i < 10; i++) {
        business.sub2();
      }
    }).start();
    new Thread(()->{
      for (int i = 0; i < 10; i++) {
        business.sub3();
      }
    }).start();
  }

  static class Business {

    Lock lock = new ReentrantLock();
    Condition condition1 = lock.newCondition();
    Condition condition2 = lock.newCondition();
    Condition condition3 = lock.newCondition();
    private int shouldSub = 1;

    public void sub2() {
      lock.lock();
      try {
        while (shouldSub != 2) {
          try {
            condition2.await();
          } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
          }
        }
        System.out.println("sub2...");
        shouldSub = 3;
        condition3.signal();
      } finally {
        lock.unlock();
      }
    }

    public void sub3() {
      lock.lock();
      try {
        while (shouldSub != 3) {
          try {
            condition3.await();
          } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
          }
        }
        System.out.println("sub3...");
        shouldSub = 1;
        condition1.signal();
      } finally {
        lock.unlock();
      }
    }

    public void sub1() {
      lock.lock();
      try {
        while (shouldSub != 1) {
          try {
            condition1.await();
          } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
          }
        }
        System.out.println("sub1...");
        shouldSub = 2;
        condition2.signal();
      } finally {
        lock.unlock();
      }
    }

  }
}
